package com.iakuil.app.common.restful;

import com.iakuil.app.common.restful.convert.DictEnumConvertFactory;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Open API接口自动配置
 *
 * @author Kai
 */
@AutoConfiguration
@ConditionalOnClass(WebMvcAutoConfiguration.class)
public class OpenApiAutoConfiguration implements WebMvcConfigurer {

    @Value("${app.name}")
    private String appName;

    @Value("${app.version}")
    private String appVersion;

    /**
     * 跨域支持
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedHeaders("*")
            .allowedMethods("GET", "POST", "OPTIONS")
            .allowedOrigins("*")
            .maxAge(3600 * 24);
    }

    /**
     * 静态资源路径
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
    }

    /**
     * 字典枚举转换工厂
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(new DictEnumConvertFactory());
    }

    /**
     * 配置参数校验策略：快速失败
     */
    @Bean
    @ConditionalOnMissingBean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory();
        return validatorFactory.getValidator();
    }

    /**
     * SpringDoc文档配置
     */
    @Bean
    @ConditionalOnMissingBean
    public OpenAPI defaultOpenApi() {
        return new OpenAPI()
            .info(new Info()
                .title(appName)
                .version(appVersion)
                .description(appName + " Ver. " + appVersion + " APIs.")
                .termsOfService("http://www.iakuil.com")
                .license(new License().name("Apache 2.0")
                    .url("http://www.iakuil.com")));
    }
}
